"""
Alpha006-025因子使用示例
======================

展示如何使用新实现的Alpha006-025因子
"""

import numpy as np
import pandas as pd
from factor.alpha101.core import Alpha101Factory, AlphaFactor
from factor.alpha101.config import list_factors_by_category

def create_sample_data(n_stocks=100, n_days=252):
    """
    创建示例数据
    
    Parameters:
    -----------
    n_stocks : int
        股票数量
    n_days : int
        交易日数量
        
    Returns:
    --------
    dict
        包含股票数据的字典
    """
    np.random.seed(42)
    
    # 生成股票代码
    stock_codes = [f"stock_{i:03d}" for i in range(n_stocks)]
    
    # 生成日期序列
    dates = pd.date_range('2023-01-01', periods=n_days, freq='D')
    
    # 生成基础价格数据
    base_price = 100.0
    returns = np.random.normal(0.0005, 0.02, (n_stocks, n_days))
    
    # 生成价格序列
    close = np.zeros((n_stocks, n_days))
    close[:, 0] = base_price + np.random.normal(0, 10, n_stocks)
    
    for i in range(1, n_days):
        close[:, i] = close[:, i-1] * (1 + returns[:, i])
    
    # 生成其他价格数据
    high = close * (1 + np.abs(np.random.normal(0, 0.01, (n_stocks, n_days))))
    low = close * (1 - np.abs(np.random.normal(0, 0.01, (n_stocks, n_days))))
    open_price = close * (1 + np.random.normal(0, 0.005, (n_stocks, n_days)))
    
    # 生成成交量数据
    volume = np.random.lognormal(10, 1, (n_stocks, n_days))
    
    # 生成VWAP
    vwap = (high + low + close) / 3.0
    
    # 计算20日平均成交量
    adv20 = np.zeros_like(volume)
    for i in range(20, n_days):
        adv20[:, i] = np.mean(volume[:, i-19:i+1], axis=1)
    adv20[:, :20] = volume[:, :20]
    
    return {
        'close': close,
        'open': open_price,
        'high': high,
        'low': low,
        'volume': volume,
        'vwap': vwap,
        'returns': returns,
        'adv20': adv20,
        'stock_codes': stock_codes,
        'dates': dates
    }

def demonstrate_single_factor():
    """演示单个因子的计算"""
    print("=== 单个因子计算示例 ===")
    
    # 创建工厂实例
    factory = Alpha101Factory(use_numba=False)
    
    # 生成数据
    data = create_sample_data(n_stocks=50, n_days=100)
    
    # 计算Alpha006因子
    factor_id = "alpha006"
    print(f"计算因子: {factor_id}")
    
    # 获取因子信息
    factor_info = factory.get_factor_info(factor_id)
    print(f"因子公式: {factor_info['formula']}")
    print(f"因子描述: {factor_info['description']}")
    print(f"因子类别: {factor_info['category']}")
    print(f"时间窗口: {factor_info['window']}")
    print(f"数据依赖: {factor_info['dependencies']}")
    
    # 计算因子值
    factor_values = factory.compute_factor(factor_id, data)
    
    print(f"因子值形状: {factor_values.shape}")
    print(f"有效值数量: {np.sum(~np.isnan(factor_values))}")
    print(f"因子值统计:")
    valid_values = factor_values[~np.isnan(factor_values)]
    if len(valid_values) > 0:
        print(f"  均值: {np.mean(valid_values):.6f}")
        print(f"  标准差: {np.std(valid_values):.6f}")
        print(f"  最小值: {np.min(valid_values):.6f}")
        print(f"  最大值: {np.max(valid_values):.6f}")
    print()

def demonstrate_batch_calculation():
    """演示批量因子计算"""
    print("=== 批量因子计算示例 ===")
    
    # 创建工厂实例
    factory = Alpha101Factory(use_numba=False)
    
    # 生成数据
    data = create_sample_data(n_stocks=30, n_days=100)
    
    # 选择要计算的因子
    factor_ids = [f"alpha{i:03d}" for i in range(6, 16)]  # Alpha006-015
    
    print(f"批量计算因子: {factor_ids}")
    
    # 批量计算
    results = factory.batch_compute(factor_ids, data)
    
    print("计算结果:")
    for factor_id, factor_values in results.items():
        if factor_values is not None:
            valid_count = np.sum(~np.isnan(factor_values))
            print(f"  {factor_id}: 有效值数量={valid_count}")
        else:
            print(f"  {factor_id}: 计算失败")
    print()

def demonstrate_factor_categories():
    """演示按类别查看因子"""
    print("=== 因子分类示例 ===")
    
    # 按类别列出因子
    categories = ['momentum', 'volume', 'price', 'volatility']
    
    for category in categories:
        factors = list_factors_by_category(category)
        # 只显示Alpha006-025范围内的因子
        factors_in_range = [f for f in factors if f in [f"alpha{i:03d}" for i in range(6, 26)]]
        if factors_in_range:
            print(f"{category}类因子: {factors_in_range}")
    print()

def demonstrate_factor_wrapper():
    """演示因子包装器的使用"""
    print("=== 因子包装器示例 ===")
    
    # 创建工厂实例
    factory = Alpha101Factory(use_numba=False)
    
    # 生成数据
    data = create_sample_data(n_stocks=20, n_days=100)
    
    # 创建因子包装器
    factor = AlphaFactor("alpha010", factory)
    
    print(f"因子ID: {factor.factor_id}")
    print(f"因子公式: {factor.formula}")
    print(f"因子描述: {factor.description}")
    print(f"因子类别: {factor.category}")
    print(f"时间窗口: {factor.window}")
    print(f"数据依赖: {factor.dependencies}")
    
    # 计算因子
    factor_values = factor.compute(data)
    
    # 验证结果
    is_valid = factor.validate_result(factor_values)
    print(f"结果验证: {'通过' if is_valid else '失败'}")
    print()

def main():
    """主函数"""
    print("Alpha006-025因子使用示例")
    print("=" * 50)
    
    try:
        # 演示各种用法
        demonstrate_single_factor()
        demonstrate_batch_calculation()
        demonstrate_factor_categories()
        demonstrate_factor_wrapper()
        
        print("✅ 所有示例运行完成！")
        
    except Exception as e:
        print(f"❌ 运行出错: {str(e)}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()